﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using MVVM.Core;
using Microsoft.Office.Interop.Excel;
using System.Runtime.InteropServices;

namespace ObjectModel.Excel
{
    /// <summary>
    /// A class that allows the linking of two OfflineRange object.
    /// </summary>
    public class LinkedRange
    {
        private OfflineSourceRange mSourceRange;

        public event EventHandler Selected;

        // Parameterless constructor for serialization
        public LinkedRange() { }

        public LinkedRange(Range range)
        {
            TargetRange = new OfflineRange(range);
            //TargetRange.Events.RangeSelected += (o, e) => { if (Selected != null) Selected(this, new EventArgs()); };

            SourceRange = new OfflineSourceRange();
        }

        public OfflineRange TargetRange { get; set; }

        public OfflineSourceRange SourceRange
        {
            get { return mSourceRange; }
            set
            {
                mSourceRange = value;
                //mSourceRange.PropertyChanged += (o, e) => { UpdateValues(); }; //TEMPORARILY DISABLED
            }
        }

    	public string Title { get { return "test title"; }
    		set {}
    	}

		public bool Checked { get { return true; }
    		set {}
    	}

        public void UpdateValues()
        {
            if (TargetRange != null && SourceRange != null)
            {
                bool transposed = false;
            	bool truncate = false;
				bool resize = false;
                Range targetRange = TargetRange.Range;
                Range sourceRange = null;

                //try
                //{
                    sourceRange = SourceRange.Range;
                //}
                //catch (InvalidOperationException)
                //{
                //    targetRange.Value = "Source not found!";
                //    return;
                //}

            	
				switch (targetRange.CompareDimensions(sourceRange))
				{
				    case RangeExtensions.DimensionEquality.Equal:
				        break;

				    case RangeExtensions.DimensionEquality.Transposed:
				        transposed = true;
				        break;

				    case RangeExtensions.DimensionEquality.NotEqual:
						// Get required action from target cell
						if(targetRange.GetResizeAction() == ResizeActions.Truncate) {
							truncate = true;
						}
						else if(targetRange.GetResizeAction() == ResizeActions.Expand) {
							resize = true;
						}
						else if (targetRange.GetResizeAction() == ResizeActions.Error) {
							throw new InvalidOperationException("Source range does not have same dimensions as target range.");	
						}
						break;
				}

				if(truncate) {
					targetRange.Value = sourceRange.GetValue(false, (int)targetRange.Height, (int)targetRange.Width);
				}
				else if(resize) {
					// Resize target range
                    Worksheet ws = targetRange.Worksheet;
                    targetRange = ws.Range[targetRange[1,1], targetRange.Offset[sourceRange.Rows.Count - 1, sourceRange.Columns.Count - 1]];
                    //targetRange = targetRange.Worksheet.Range[targetRange.Worksheet.Cells[targetRange.Row, targetRange.Column],
                    //    targetRange.Worksheet.Cells[targetRange.Row + sourceRange.Rows.Count -1, targetRange.Column + sourceRange.Columns.Count -1]];
					
					targetRange.Value = sourceRange.GetValue(false);

				}
				else
				{
				 targetRange.Value = sourceRange.GetValue(transposed);
				}
            }
        }
    }
}
